home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Graphics Plus
/
Graphics Plus.iso
/
msdos
/
fractal
/
frasr182
/
fractint.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-08-18
|
56KB
|
1,757 lines
/*
FRACTINT - The Ultimate Fractal Generator
Main Routine
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#ifndef XFRACT
#include <dos.h>
#include <stdarg.h>
#else
#include <varargs.h>
#endif
#include <ctype.h>
#include "prototyp.h"
/* routines in this module */
static void cmp_line_cleanup();
static void move_zoombox(int);
static int call_line3d(BYTE *pixels, int linelen);
void clear_zoombox();
static void note_zoom();
static void restore_zoom();
static void setup287code();
#ifndef XFRACT
extern int timer(int timertype,int(*subrtn)(),...);
#else
extern int timer();
#endif
#define PUTTHEMHERE 1 /* stuff common external arrays here */
#include "fractint.h"
#include "mpmath.h"
#include "fractype.h"
#include "helpdefs.h"
long timer_start,timer_interval; /* timer(...) start & total */
extern int timerflag;
int adapter; /* Video Adapter chosen from list in ...h */
extern double xcjul, ycjul;
extern int soundflag;
extern int julibrot;
extern char gifmask[];
extern int TPlusErr;
extern int save_release, bailout;
extern int Transparent3D, far NewTPFractal, tpdepth;
extern int AntiAliasing, Shadowing;
extern int pot16bit; /* save 16 bit values for continuous potential */
extern int disk16bit; /* disk video up & running with 16 bit values */
extern int video_type; /* coded value indicating video adapter type */
extern int usr_biomorph;
extern int escape_exit;
extern int forcesymmetry;
extern float screenaspect;
extern char readname[]; /* name of fractal input file */
extern int showfile; /* zero if display of file is pending */
#define MAXHISTORY 10 /* save this many historical rcds */
struct historystruct { /* history structure */
int fractype; /* fractal type */
double param[MAXPARAMS];/* parameters */
double xxmin; /* top left */
double yymax; /* top left */
double xxmax; /* bottom right */
double yymin; /* bottom right */
double xx3rd; /* bottom left */
double yy3rd; /* bottom left */
} far *history;
char *fract_dir1="", *fract_dir2="";
#ifdef __TURBOC__
/* yes, I *know* it's supposed to be compatible with Microsoft C,
but some of the routines need to know if the "C" code
has been compiled with Turbo-C. This flag is a 1 if FRACTINT.C
(and presumably the other routines as well) has been compiled
with Turbo-C. */
int compiled_by_turboc = 1;
/* set size to be used for overlays, a bit bigger than largest (help) */
unsigned _ovrbuffer = 54 * 64; /* that's 54k for overlays, counted in paragraphs */
#else
int compiled_by_turboc = 0;
#endif
extern char savename[]; /* save files using this name */
extern char preview; /* 3D preview mode flag */
extern char temp1[]; /* temporary strings */
extern int debugflag; /* internal use only - you didn't see this */
/*
the following variables are out here only so
that the calcfract() and assembler routines can get at them easily
*/
int active_system = 0; /* 0 for DOS, WINFRAC for Windows */
int dotmode; /* video access method */
int textsafe2; /* textsafe override from videotable */
int oktoprint; /* 0 if printf() won't work */
int sxdots,sydots; /* # of dots on the physical screen */
int sxoffs,syoffs; /* physical top left of logical screen */
int xdots, ydots; /* # of dots on the logical screen */
double dxsize, dysize; /* xdots-1, ydots-1 */
int colors; /* maximum colors available */
int maxit; /* try this many iterations */
int boxcount; /* 0 if no zoom-box yet */
int zrotate; /* zoombox rotation */
double zbx,zby; /* topleft of zoombox */
double zwidth,zdepth,zskew; /* zoombox size & shape */
int fractype; /* if == 0, use Mandelbrot */
char stdcalcmode; /* '1', '2', 'g', 'b' */
long creal, cimag; /* real, imag'ry parts of C */
long delx, dely; /* screen pixel increments */
long delx2, dely2; /* screen pixel increments */
double delxx, delyy; /* screen pixel increments */
double delxx2, delyy2; /* screen pixel increments */
long delmin; /* for calcfrac/calcmand */
double ddelmin; /* same as a double */
double param[MAXPARAMS]; /* parameters */
double potparam[3]; /* three potential parameters*/
long fudge; /* 2**fudgefactor */
long l_at_rad; /* finite attractor radius */
double f_at_rad; /* finite attractor radius */
int bitshift; /* fudgefactor */
int badconfig = 0; /* 'fractint.cfg' ok? */
int diskisactive; /* disk-video drivers flag */
int diskvideo; /* disk-video access flag */
int hasinverse = 0;
/* note that integer grid is set when integerfractal && !invert; */
/* otherwise the floating point grid is set; never both at once */
long far *lx0, far *ly0; /* x, y grid */
long far *lx1, far *ly1; /* adjustment for rotate */
/* note that lx1 & ly1 values can overflow into sign bit; since */
/* they're used only to add to lx0/ly0, 2s comp straightens it out */
double far *dx0, far *dy0; /* floating pt equivs */
double far *dx1, far *dy1;
int integerfractal; /* TRUE if fractal uses integer math */
/* usr_xxx is what the user wants, vs what we may be forced to do */
char usr_stdcalcmode;
int usr_periodicitycheck;
int usr_distest;
char usr_floatflag;
int viewwindow; /* 0 for full screen, 1 for window */
float viewreduction; /* window auto-sizing */
int viewcrop; /* nonzero to crop default coords */
float finalaspectratio; /* for view shape and rotation */
int viewxdots,viewydots; /* explicit view sizing */
extern int inside; /* inside color: 1=blue */
extern int outside; /* outside color, if set */
extern int cyclelimit; /* color-rotator upper limit */
extern int display3d; /* 3D display flag: 0 = OFF */
extern int overlay3d; /* 3D overlay flag: 0 = OFF */
extern int boxcolor; /* zoom box color */
extern int color_bright; /* set by find_special_colors */
#ifndef XFRACT
extern BYTE dacbox[256][3]; /* Video-DAC (filled in by SETVIDEO) */
extern BYTE olddacbox[256][3]; /* backup copy of the Video-DAC */
#else
BYTE dacbox[256][3]; /* Video-DAC (filled in by SETVIDEO) */
BYTE olddacbox[256][3]; /* backup copy of the Video-DAC */
#endif
extern struct videoinfo far videotable[];
extern BYTE far *mapdacbox; /* default dacbox when map= specified */
extern int daclearn, daccount; /* used by the color-cyclers */
extern SEGTYPE extraseg; /* used by Save-to-DISK routines */
extern int cpu; /* cpu type */
extern int fpu; /* fpu type */
extern int iit; /* iit fpu? */
extern int lookatmouse; /* used to select mouse mode */
extern int (*outln)(BYTE *, int); /* called in decoder */
void (*outln_cleanup)();
extern int filetype; /* GIF or other */
/* variables defined by the command line/files processor */
extern double inversion[];
extern int invert; /* non-zero if inversion active */
extern int initbatch; /* 1 if batch run (no kbd) */
/* 2 batch, no save */
/* 3 user interrupt, errorlevel 2 */
/* 4 program error errorlevel 1, save */
/* 5 program error errorlevel 1, don't save */
/* -1 complete first, then set to 1 */
extern int initmode; /* initial video mode */
extern int goodmode; /* video.asm sets nonzero if mode ok */
extern int initcyclelimit; /* initial cycle limit */
extern int LogFlag; /* non-zero if logarithmic palettes */
extern int reallyega; /* == 0 if it's really an EGA */
extern char showbox; /* flag to show box and vector in preview */
extern unsigned initsavetime; /* timed save interval */
int comparegif=0; /* compare two gif files flag */
int timedsave=0; /* when doing a timed save */
extern long saveticks, savebase; /* timed save vars for general.asm */
extern int finishrow; /* for general.asm timed save */
int resave_flag=0; /* tells encoder not to incr filename */
int started_resaves=0; /* but incr on first resave */
int save_system; /* from and for save files */
int tabmode = 1; /* tab display enabled */
extern int got_status;
extern int loaded3d;
extern int colorstate,colorpreloaded; /* comments in cmdfiles */
extern int functionpreloaded; /* set in cmdfiles for old bifs JCO 7/5/92 */
extern int show_orbit;
#ifdef XFRACT
extern int XZoomWaiting;
#endif
/* for historical reasons (before rotation): */
/* top left corner of screen is (xxmin,yymax) */
/* bottom left corner of screen is (xx3rd,yy3rd) */
/* bottom right corner of screen is (xxmax,yymin) */
double xxmin,xxmax,yymin,yymax,xx3rd,yy3rd; /* selected screen corners */
long xmin, xmax, ymin, ymax, x3rd, y3rd; /* integer equivs */
double sxmin,sxmax,symin,symax,sx3rd,sy3rd; /* displayed screen corners */
double plotmx1,plotmx2,plotmy1,plotmy2; /* real->screen multipliers */
int calc_status; /* -1 no fractal */
/* 0 parms changed, recalc reqd */
/* 1 actively calculating */
/* 2 interrupted, resumable */
/* 3 interrupted, not resumable */
/* 4 completed */
long calctime;
int max_colors; /* maximum palette size */
extern int max_kbdcount; /* governs keyboard-check speed */
int zoomoff; /* = 0 when zoom is disabled */
extern int nxtscreenflag; /* for cellular next screen generation */
static int far fromtext_flag = 0; /* = 1 if we're in graphics mode */
int savedac; /* save-the-Video DAC flag */
void main(int argc, char **argv)
{
double jxxmin, jxxmax, jyymin, jyymax; /* "Julia mode" entry point */
double jxx3rd, jyy3rd;
int frommandel; /* if julia entered from mandel */
int axmode, bxmode, cxmode, dxmode; /* video mode (BIOS ##) */
int historyptr; /* pointer into history tbl */
int historyflag; /* are we backing off in history? */
int kbdchar; /* keyboard key-hit value */
int kbdmore; /* continuation variable */
int i, k; /* temporary loop counters */
double ftemp; /* fp temp */
char stacked=0; /* flag to indicate screen stacked */
initasmvars(); /* initialize ASM stuff */
if (extraseg == 0 /* oops. not enough memory */
|| (history = (struct historystruct far * ) farmemalloc((unsigned long)
(MAXHISTORY * sizeof(*history)))) == NULL
|| (ly0 = (long far *) farmemalloc(4096L)) == NULL) {
buzzer(2);
printf(" I'm sorry, but you don't have enough free memory \n");
printf(" to run this program.\n\n");
exit(1);
}
farmemfree((BYTE far *)ly0); /* was just to check for min space */
dx0 = MK_FP(extraseg,0);
dy1 = (dx1 = (dy0 = dx0 + MAXPIXELS) + MAXPIXELS) + MAXPIXELS;
lx0 = (long far *) dx0;
ly1 = (lx1 = (ly0 = lx0 + MAXPIXELS) + MAXPIXELS) + MAXPIXELS;
historyptr = 0; /* initialize history ptr */
historyflag = 0;
history[historyptr].fractype = -1;
load_videotable(1); /* load fractint.cfg, no message yet if bad */
#ifdef XFRACT
UnixInit();
#endif
init_help();
restart: /* insert key re-starts here */
cmdfiles(argc,argv); /* process the command-line */
if(debugflag==450 && strcmp(savename,"fract001") != 0)
{
char name[80];
strcpy(name,savename);
strcat(name,".gif");
if(access(name,0)==0)
exit(0);
}
#ifdef XFRACT
initUnixWindow();
#endif
memcpy(olddacbox,dacbox,256*3); /* save in case colors= present */
if (debugflag == 8088) cpu = 86; /* for testing purposes */
if (debugflag == 2870 && fpu >= 287 ) fpu = 287; /* for testing purposes */
if (debugflag == 870 && fpu >= 87 ) fpu = 87; /* for testing purposes */
if (debugflag == 70) fpu = 0; /* for testing purposes */
if (getenv("NO87")) fpu = 0;
fract_dir1 = getenv("FRACTDIR");
if (fract_dir1==NULL) {
fract_dir1 = ".";
}
#ifdef SRCDIR
fract_dir2 = SRCDIR;
#else
fract_dir2 = ".";
#endif
if (fpu == 0) iit = 0;
if (fpu >= 287 && debugflag != 72) /* Fast 287 math */
setup287code();
/* IIT math coprocessor chip logic */
if(iit == 0 && fpu)
if(IITCoPro())
iit = 3; /* detect iit chip */
if(iit < 0) iit = 0; /* user wants chip turned off */
if(iit>0)
{
if(F4x4Check())
iit = 2; /* semaphore TSR is installed */
else if(iit == 3)
iit = 0; /* we detetct chip but no tsr - don't use */
/* else user forced iit == 1 */
}
adapter_detect(); /* check what video is really present */
if (debugflag >= 9002 && debugflag <= 9100) /* for testing purposes */
if (video_type > (debugflag-9000)/2) /* adjust the video value */
video_type = (debugflag-9000)/2;
diskisactive = 0; /* disk-video is inactive */
diskvideo = 0; /* disk driver is not in use */
setvideotext(); /* switch to text mode */
calc_status = -1; /* no active fractal image */
savedac = 0; /* don't save the VGA DAC */
if (debugflag == 10000) /* check for free memory */
showfreemem();
#ifndef XFRACT
if (badconfig < 0) /* fractint.cfg bad, no msg yet */
bad_fractint_cfg_msg();
#endif
max_colors = 256; /* the Windows version is lower */
max_kbdcount=(cpu==386) ? 80 : 30; /* check the keyboard this often */
if (showfile && initmode < 0) {
intro(); /* display the credits screen */
if (keypressed() == ESC) {
getakey();
goodbye();
}
}
if (colorpreloaded)
memcpy(dacbox,olddacbox,256*3); /* restore in case colors= present */
if (!functionpreloaded)
set_if_old_bif();
stacked = 0;
restorestart:
lookatmouse = 0; /* ignore mouse */
while (showfile <= 0) { /* image is to be loaded */
char *hdg;
tabmode = 0;
if (overlay3d) {
hdg = "Select File for 3D Overlay";
helpmode = HELP3DOVLY;
}
else if (display3d) {
hdg = "Select File for 3D Transform";
helpmode = HELP3D;
}
else {
hdg = "Select File to Restore";
helpmode = HELPSAVEREST;
}
if (showfile < 0 && getafilename(hdg,gifmask,readname) < 0) {
showfile = 1; /* cancelled */
initmode = -1;
break;
}
showfile = 0;
helpmode = -1;
tabmode = 1;
if(stacked)
{
discardscreen();
setvideotext();
stacked = 0;
}
if (read_overlay() == 0) /* read hdr, get video mode */
break; /* got it, exit */
showfile = -1; /* retry */
}
helpmode = HELPMENU; /* now use this help mode */
tabmode = 1;
lookatmouse = 0; /* ignore mouse */
if ((overlay3d || stacked) && initmode < 0) { /* overlay command failed */
unstackscreen(); /* restore the graphics screen */
stacked = 0;
overlay3d = 0; /* forget overlays */
display3d = 0; /* forget 3D */
if (calc_status > 0 && calc_status !=2)
calc_status = 0;
goto resumeloop; /* ooh, this is ugly */
}
savedac = 0; /* don't save the VGA DAC */
imagestart: /* calc/display a new image */
if(stacked)
{
discardscreen();
stacked = 0;
}
#ifdef XFRACT
usr_floatflag = 1;
#endif
got_status = -1; /* for tab_display */
if (showfile)
if (calc_status > 0) /* goto imagestart implies re-calc */
calc_status = 0;
if (initbatch == 0)
lookatmouse = -PAGE_UP; /* just mouse left button, == pgup */
cyclelimit = initcyclelimit; /* default cycle limit */
frommandel = 0;
adapter = initmode; /* set the video adapter up */
initmode = -1; /* (once) */
while (adapter < 0) { /* cycle through instructions */
if (initbatch) { /* batch, nothing to do */
initbatch = 4; /* exit with error condition set */
goodbye();
}
kbdchar = main_menu(0);
if (kbdchar == INSERT) goto restart; /* restart pgm on Insert Key */
if (kbdchar == DELETE) /* select video mode list */
kbdchar = select_video_mode(-1);
if ((adapter = check_vidmode_key(0,kbdchar)) >= 0)
break; /* got a video mode now */
#ifndef XFRACT
if ('A' <= kbdchar && kbdchar <= 'Z')
kbdchar = tolower(kbdchar);
#endif
if (kbdchar == 'd') { /* shell to DOS */
setclear();
printf("\n\nShelling to DOS - type 'exit' to return\n\n");
shell_to_dos();
goto imagestart;
}
#ifndef XFRACT
if (kbdchar == '@') { /* execute commands */
#else
if (kbdchar == F2 || kbdchar == '@') { /* We mapped @ to F2 */
#endif
if ((get_commands() & 4) == 0)
goto imagestart;
kbdchar = '3'; /* 3d=y so fall thru '3' code */
}
#ifndef XFRACT
if (kbdchar == 'r' || kbdchar == '3' || kbdchar == '#') {
#else
if (kbdchar == 'r' || kbdchar == '3' || kbdchar == F3) {
#endif
display3d = 0;
if (kbdchar == '3' || kbdchar == '#' || kbdchar == F3)
display3d = 1;
setvideotext(); /* switch to text mode */
showfile = -1;
goto restorestart;
}
if (kbdchar == 't') { /* set fractal type */
julibrot = 0;
get_fracttype();
goto imagestart;
}
if (kbdchar == 'x') { /* generic toggle switch */
get_toggles();
goto imagestart;
}
if (kbdchar == 'y') { /* generic toggle switch */
get_toggles2();
goto imagestart;
}
if (kbdchar == 'z') { /* type specific parms */
get_fract_params(1);
goto imagestart;
}
if (kbdchar == 'v') { /* view parameters */
get_view_params();
goto imagestart;
}
if (kbdchar == 'f') { /* floating pt toggle */
if (usr_floatflag == 0)
usr_floatflag = 1;
else
usr_floatflag = 0;
goto imagestart;
}
if (kbdchar == 'i') { /* set 3d fractal parms */
get_fract3d_params(); /* get the parameters */
goto imagestart;
}
if (kbdchar == 'g') {
get_cmd_string(); /* get command string */
goto imagestart;
}
/* buzzer(2); */ /* unrecognized key */
}
zoomoff = 1; /* zooming is enabled */
helpmode = HELPMAIN; /* now use this help mode */
while (1) { /* eternal loop */
if (calc_status != 2 || showfile == 0) {
#ifdef XFRACT
if (resizeWindow()) {
calc_status = -1;
}
#endif
far_memcpy((char far *)&videoentry,(char far *)&videotable[adapter],
sizeof(videoentry));
axmode = videoentry.videomodeax; /* video mode (BIOS call) */
bxmode = videoentry.videomodebx; /* video mode (BIOS call) */
cxmode = videoentry.videomodecx; /* video mode (BIOS call) */
dxmode = videoentry.videomodedx; /* video mode (BIOS call) */
dotmode = videoentry.dotmode; /* assembler dot read/write */
xdots = videoentry.xdots; /* # dots across the screen */
ydots = videoentry.ydots; /* # dots down the screen */
colors = videoentry.colors; /* # colors available */
textsafe2 = dotmode / 100;
dotmode %= 100;
sxdots = xdots;
sydots = ydots;
sxoffs = syoffs = 0;
diskvideo = 0; /* set diskvideo flag */
if (dotmode == 11) /* default assumption is disk */
diskvideo = 2;
memcpy(olddacbox,dacbox,256*3); /* save the DAC */
diskisactive = 1; /* flag for disk-video routines */
if (overlay3d) {
unstackscreen(); /* restore old graphics image */
overlay3d = 0;
}
else {
setvideomode(axmode,bxmode,cxmode,dxmode); /* switch video modes */
if (goodmode == 0) {
static char far msg[] = {"That video mode is not available with your adapter."};
static char far TPlusStr[] = "This video mode requires 'noninterlaced=yes'";
if(TPlusErr) {
stopmsg(0, TPlusStr);
TPlusErr = 0;
}
else
stopmsg(0,msg);
initmode = -1;
setvideotext(); /* switch to text mode */
goto restorestart;
}
if(Transparent3D && curfractalspecific->orbitcalc == Formula) {
char far *ErrMsg;
if((ErrMsg = TrueColorAutoDetect()) != ((char far*)0)) {
stopmsg(0, ErrMsg);
Transparent3D = 0;
}
else {
tpdepth = 0;
NewTPFractal = 1;
}
}
else if(AntiAliasing) {
if(dotmode != 11) {
static char far DiskVidError[] =
"Anti-aliasing resolution too high, try a lower value or lower\n\
screen resolution.";
/* Ensure the absolute resolution is < MAXPIXELS */
if(AntiAliasing >= 8 ||
((long)xdots << AntiAliasing) > MAXPIXELS)
goto AntiAliasError;
if(!colors)
TrueColorAutoDetect();
if(SetupShadowVideo() != 0) {
AntiAliasError:
stopmsg(0, DiskVidError);
initmode = -1;
setvideotext(); /* switch to text mode */
goto restorestart;
}
}
}
}
diskisactive = 0; /* flag for disk-video routines */
if (savedac || colorpreloaded) {
memcpy(dacbox,olddacbox,256*3); /* restore the DAC */
spindac(0,1);
colorpreloaded = 0;
}
else { /* reset DAC to defaults, which setvideomode has done for us */
if (mapdacbox) { /* but there's a map=, so load that */
far_memcpy((char far *)dacbox,mapdacbox,768);
spindac(0,1);
}
else if ((dotmode == 11 && colors == 256) || !colors) {
/* disk video, setvideomode via bios didn't get it right, so: */
#ifndef XFRACT
ValidateLuts("default"); /* read the default palette file */
#endif
}
colorstate = 0;
}
if (viewwindow) {
ftemp = finalaspectratio
* (double)sydots / (double)sxdots / screenaspect;
if ((xdots = viewxdots)) { /* xdots specified */
if ((ydots = viewydots) == 0) /* calc ydots? */
ydots = (double)xdots * ftemp + 0.5;
}
else
if (finalaspectratio <= screenaspect) {
xdots = (double)sxdots / viewreduction + 0.5;
ydots = (double)xdots * ftemp + 0.5;
}
else {
ydots = (double)sydots / viewreduction + 0.5;
xdots = (double)ydots / ftemp + 0.5;
}
if (xdots > sxdots || ydots > sydots) {
static char far msg[] = {"View window too large; using full screen."};
stopmsg(0,msg);
xdots = sxdots;
ydots = sydots;
}
else if (xdots <= sxdots/20 || ydots <= sydots/20) { /* so ssg works */
static char far msg[] = {"View window too small; using full screen."};
stopmsg(0,msg);
xdots = sxdots;
ydots = sydots;
}
sxoffs = (sxdots - xdots) / 2;
syoffs = (sydots - ydots) / 3;
}
dxsize = xdots - 1; /* convert just once now */
dysize = ydots - 1;
}
if(savedac == 0)
savedac = 2; /* assume we save next time (except jb) */
else
savedac = 1; /* assume we save next time */
if (initbatch == 0)
lookatmouse = -PAGE_UP; /* mouse left button == pgup */
if(showfile == 0) { /* loading an image */
outln_cleanup = NULL; /* outln routine can set this */
if (display3d) /* set up 3D decoding */
outln = call_line3d;
else if(filetype >= 1) /* old .tga format input file */
outln = outlin16;
else if(comparegif) /* debug 50 */
outln = cmp_line;
else if(pot16bit) { /* .pot format input file */
if (pot_startdisk() < 0)
{ /* pot file failed? */
extern int potflag;
showfile = 1;
potflag = 0;
pot16bit = 0;
initmode = -1;
calc_status = 2; /* "resume" without 16-bit */
setvideotext();
get_fracttype();
goto imagestart;
}
outln = pot_line;
}
else /* regular gif/fra input file */
if(soundflag > 0)
outln = sound_line; /* sound decoding */
else
outln = out_line; /* regular decoding */
if(filetype == 0)
{
if(iit == 2 && usr_floatflag != 0)
if(F4x4Lock()==0)
iit = -1; /* semaphore not free - no iit */
if(debugflag==2224)
{
char buf[80];
sprintf(buf,"iit=%d floatflag=%d",iit,usr_floatflag);
stopmsg(4,(char far *)buf);
}
i = funny_glasses_call(gifview);
if(iit == 2)
F4x4Free(); /* unlock semaphore */
else if(iit == -1)
iit = 2; /* semaphore operating */
}
else
i = funny_glasses_call(tgaview);
if(outln_cleanup) /* cleanup routine defined? */
(*outln_cleanup)();
if(i == 0)
buzzer(0);
else {
calc_status = -1;
if (keypressed()) {
buzzer(1);
while (keypressed()) getakey();
texttempmsg("*** load incomplete ***");
}
}
}
zoomoff = 1; /* zooming is enabled */
if (dotmode == 11 || (curfractalspecific->flags&NOZOOM) != 0)
zoomoff = 0; /* for these cases disable zooming */
calcfracinit();
#ifdef XFRACT
schedulealarm(1);
#endif
sxmin = xxmin; /* save 3 corners for zoom.c ref points */
sxmax = xxmax;
sx3rd = xx3rd;
symin = yymin;
symax = yymax;
sy3rd = yy3rd;
if (history[0].fractype == -1) /* initialize the history file */
for (i = 0; i < MAXHISTORY; i++) {
int j;
history[i].xxmax = xxmax;
history[i].xxmin = xxmin;
history[i].yymax = yymax;
history[i].yymin = yymin;
history[i].xx3rd = xx3rd;
history[i].yy3rd = yy3rd;
for(j=0;j<MAXPARAMS;j++)
history[i].param[j] = param[j];
history[i].fractype = fractype;
}
if ( history[historyptr].xxmax != xxmax || /* save any (new) zoom data */
history[historyptr].xxmin != xxmin ||
history[historyptr].yymax != yymax ||
history[historyptr].yymin != yymin ||
history[historyptr].xx3rd != xx3rd ||
history[historyptr].yy3rd != yy3rd ||
history[historyptr].param[0] != param[0] ||
history[historyptr].param[1] != param[1] ||
history[historyptr].param[2] != param[2] ||
history[historyptr].param[3] != param[3] ||
history[historyptr].param[4] != param[4] ||
history[historyptr].param[5] != param[5] ||
history[historyptr].param[6] != param[6] ||
history[historyptr].param[7] != param[7] ||
history[historyptr].param[8] != param[8] ||
history[historyptr].param[9] != param[9] ||
history[historyptr].fractype != fractype) {
int j;
if (historyflag == 0) /* if we're not backing off for <\> */
if (++historyptr == MAXHISTORY) historyptr = 0;
history[historyptr].xxmax = xxmax;
history[historyptr].xxmin = xxmin;
history[historyptr].yymax = yymax;
history[historyptr].yymin = yymin;
history[historyptr].xx3rd = xx3rd;
history[historyptr].yy3rd = yy3rd;
for(j=0;j<MAXPARAMS;j++)
history[historyptr].param[j] = param[j];
history[historyptr].fractype = fractype;
}
historyflag = 0;
if (display3d || showfile) { /* paranoia: these vars don't get set */
save_system = active_system; /* unless really doing some work, */
} /* so simple <r> + <s> keeps number */
if(showfile == 0) { /* image has been loaded */
showfile = 1;
if (initbatch == 1 && calc_status == 2)
initbatch = -1; /* flag to finish calc before save */
if (loaded3d) /* 'r' of image created with '3' */
display3d = 1; /* so set flag for 'b' command */
}
else { /* draw an image */
diskisactive = 1; /* flag for disk-video routines */
if (initsavetime != 0 /* autosave and resumable? */
&& (curfractalspecific->flags&NORESUME) == 0) {
savebase = readticker(); /* calc's start time */
saveticks = (long)initsavetime * 1092; /* bios ticks/minute */
if ((saveticks & 65535L) == 0)
++saveticks; /* make low word nonzero */
finishrow = -1;
}
if(Transparent3D && curfractalspecific->orbitcalc == Formula)
i = Transp3DFnct();
else {
i = calcfract(); /* draw the fractal using "C" */
if(AntiAliasing && i == 0)
AntiAliasPass();
}
if (i == 0)
buzzer(0); /* finished!! */
saveticks = 0; /* turn off autosave timer */
if (dotmode == 11 && i == 0) /* disk-video */
dvid_status(0,"Image has been completed");
diskisactive = 0; /* flag for disk-video routines */
}
#ifndef XFRACT
boxcount = 0; /* no zoom box yet */
zwidth = 0;
#else
if (!XZoomWaiting) {
boxcount = 0; /* no zoom box yet */
zwidth = 0;
}
#endif
if (fractype == PLASMA && cpu > 88) {
cyclelimit = 256; /* plasma clouds need quick spins */
daccount = 256;
daclearn = 1;
}
resumeloop: /* return here on failed overlays */
kbdmore = 1;
while (kbdmore == 1) { /* loop through command keys */
if (timedsave != 0) {
if (timedsave == 1) { /* woke up for timed save */
getakey(); /* eat the dummy char */
kbdchar = 's'; /* do the save */
resave_flag = 1;
timedsave = 2;
}
else { /* save done, resume */
timedsave = 0;
resave_flag = 2;
kbdchar = ENTER;
}
}
else if (initbatch == 0) { /* not batch mode */
lookatmouse = (zwidth == 0) ? -PAGE_UP : 3;
if (calc_status == 2 && zwidth == 0 && !keypressed()) {
kbdchar = ENTER; /* no visible reason to stop, continue */
} else { /* wait for a real keystroke */
#ifndef XFRACT
while (!keypressed()) { } /* enables help */
#else
waitkeypressed(0);
#endif
kbdchar = getakey();
if (kbdchar == ESC || kbdchar == 'm' || kbdchar == 'M') {
if (kbdchar == ESC && escape_exit != 0)
/* don't ask, just get out */
goodbye();
stackscreen();
#ifndef XFRACT
kbdchar = main_menu(1);
#else
if (XZoomWaiting) {
kbdchar = ENTER;
} else {
kbdchar = main_menu(1);
if (XZoomWaiting) {
kbdchar = ENTER;
}
}
#endif
if (kbdchar == '\\'
|| check_vidmode_key(0,kbdchar) >= 0)
discardscreen();
else if (kbdchar == 'x' || kbdchar == 'y' ||
kbdchar == 'z' || kbdchar == 'g' )
fromtext_flag = 1;
else
unstackscreen();
}
}
}
else { /* batch mode, fake next keystroke */
if (initbatch == -1) { /* finish calc */
kbdchar = ENTER;
initbatch = 1;
}
else if (initbatch == 1 || initbatch == 4 ) { /* save-to-disk */
/*
while(keypressed())
getakey();
*/
if (debugflag == 50)
kbdchar = 'r';
else
kbdchar = 's';
if(initbatch == 1) initbatch = 2;
if(initbatch == 4) initbatch = 5;
}
else {
if(calc_status != 4) initbatch = 3; /* bailout with error */
goodbye(); /* done, exit */
}
}
#ifndef XFRACT
if ('A' <= kbdchar && kbdchar <= 'Z')
kbdchar = tolower(kbdchar);
#endif
switch (kbdchar) {
int x,y,v;
case 't': /* new fractal type */
julibrot = 0;
clear_zoombox();
stackscreen();
if ((i = get_fracttype()) >= 0) {
discardscreen();
savedac = 0;
if (i == 0) {
initmode = adapter;
frommandel = 0;
}
else
if (initmode < 0) /* it is supposed to be... */
setvideotext(); /* reset to text mode */
goto imagestart;
}
unstackscreen();
break;
case 24: /* Ctl-X, Ctl-Y, CTL-Z do flipping */
case 25:
case 26:
flip_image(kbdchar);
break;
case 'x': /* invoke options screen */
case 'y':
case 'z': /* type specific parms */
case 'g':
if (fromtext_flag == 1)
fromtext_flag = 0;
else
stackscreen();
if (kbdchar == 'x')
i = get_toggles();
else if (kbdchar == 'y')
i = get_toggles2();
else if (kbdchar =='z')
i = get_fract_params(1);
else
i = get_cmd_string();
if (i > 0) { /* time to redraw? */
discardscreen();
kbdmore = calc_status = 0;
}
else
unstackscreen();
break;
#ifndef XFRACT
case '@': /* execute commands */
#else
case F2: /* execute commands */
#endif
stackscreen();
i = get_commands();
if (initmode != -1) { /* video= was specified */
adapter = initmode;
initmode = -1;
i |= 1;
savedac = 0;
}
else if (colorpreloaded) { /* colors= was specified */
spindac(0,1);
colorpreloaded = 0;
}
else if ((i & 8)) /* reset was specified */
savedac = 0;
if ((i & 4)) { /* 3d = was specified */
kbdchar = '3';
unstackscreen();
goto do_3d_transform; /* pretend '3' was keyed */
}
if ((i & 1)) { /* fractal parameter changed */
discardscreen();
if(!functionpreloaded)
set_if_old_bif(); /* old bifs need function set, JCO 7/5/92 */
if(fractype==MANDELTRIG && usr_floatflag==1
&& save_release < 1800 && bailout == 0)
bailout = 2500;
if(fractype==LAMBDATRIG && usr_floatflag==1
&& save_release < 1800 && bailout == 0)
bailout = 2500;
kbdmore = calc_status = 0;
}
else
unstackscreen();
break;
case 'v': /* invoke options screen */
i = get_view_params(); /* get the parameters */
if (i > 0) /* time to redraw? */
kbdmore = calc_status = 0;
break;
case 'f': /* floating pt toggle */
if (usr_floatflag == 0)
usr_floatflag = 1;
else
usr_floatflag = 0;
initmode = adapter;
goto imagestart;
case 'i': /* 3d fractal parms */
if (get_fract3d_params() >= 0) /* get the parameters */
calc_status = kbdmore = 0; /* time to redraw */
break;
case 'a': /* starfield parms */
clear_zoombox();
if (get_starfield_params() >= 0) {
if (starfield() >= 0)
calc_status = 0;
continue;
}
break;
case 15: /* ctrl-o */
case 'o':
/* must use standard fractal and have a float variant */
if(fractalspecific[fractype].calctype == StandardFractal &&
(fractalspecific[fractype].isinteger == 0 ||
fractalspecific[fractype].tofloat != NOFRACTAL))
{
clear_zoombox();
Jiim(ORBIT);
}
break;
case SPACE: /* spacebar, toggle mand/julia */
if (fractype == CELLULAR) {
if(nxtscreenflag)
nxtscreenflag = 0; /* toggle flag to stop generation */
else
nxtscreenflag = 1; /* toggle flag to generate next screen */
calc_status = 2;
kbdmore = 0;
}
else {
if (curfractalspecific->tojulia != NOFRACTAL
&& param[0] == 0.0 && param[1] == 0.0) {
/* switch to corresponding Julia set */
if(1)
{
int key;
if(fractype==MANDEL || fractype==MANDELFP)
hasinverse=1;
else
hasinverse=0;
clear_zoombox();
Jiim(JIIM);
key = getakey(); /* flush keyboard buffer */
if(key != SPACE)
{
ungetakey(key);
break;
}
}
fractype = curfractalspecific->tojulia;
curfractalspecific = &fractalspecific[fractype];
if(xcjul == BIG || ycjul == BIG)
{
param[0] = (xxmax + xxmin) / 2;
param[1] = (yymax + yymin) / 2;
}
else
{
param[0] = xcjul;
param[1] = ycjul;
xcjul = ycjul = BIG;
}
jxxmin = sxmin; jxxmax = sxmax;
jyymax = symax; jyymin = symin;
jxx3rd = sx3rd; jyy3rd = sy3rd;
frommandel = 1 ;
xxmin = curfractalspecific->xmin;
xxmax = curfractalspecific->xmax;
yymin = curfractalspecific->ymin;
yymax = curfractalspecific->ymax;
xx3rd = xxmin;
yy3rd = yymin;
if (usr_distest == 0 && usr_biomorph != -1 && bitshift != 29) {
xxmin *= 3.0;
xxmax *= 3.0;
yymin *= 3.0;
yymax *= 3.0;
xx3rd *= 3.0;
yy3rd *= 3.0;
}
zoomoff = 1;
calc_status = 0;
kbdmore = 0;
}
else if (curfractalspecific->tomandel != NOFRACTAL) {
/* switch to corresponding Mandel set */
fractype = curfractalspecific->tomandel;
curfractalspecific = &fractalspecific[fractype];
if (frommandel) {
xxmin = jxxmin; xxmax = jxxmax;
yymin = jyymin; yymax = jyymax;
xx3rd = jxx3rd; yy3rd = jyy3rd;
}
else {
double ccreal,ccimag;
ccreal = (curfractalspecific->xmax - curfractalspecific->xmin) / 2;
ccimag = (curfractalspecific->ymax - curfractalspecific->ymin) / 2;
xxmin = xx3rd = param[0] - ccreal;
xxmax = param[0] + ccreal;
yymin = yy3rd = param[1] - ccimag;
yymax = param[1] + ccimag;
}
param[0] = 0;
param[1] = 0;
zoomoff = 1;
calc_status = 0;
kbdmore = 0;
}
else
buzzer(2); /* can't switch */
} /* end of else for if == cellular */
break;
case 'j': /* inverse julia toggle */
/* if the inverse types proliferate, something more elegant will
be needed */
if(fractype==JULIA || fractype==JULIAFP || fractype==INVERSEJULIA)
{
static int oldtype = -1;
if(fractype==JULIA || fractype==JULIAFP)
{
oldtype=fractype;
fractype=INVERSEJULIA;
}
else if(fractype==INVERSEJULIA)
{
if(oldtype != -1)
fractype=oldtype;
else
fractype=JULIA;
}
curfractalspecific = &fractalspecific[fractype];
zoomoff = 1;
calc_status = 0;
kbdmore = 0;
}
#if 0
else if(fractype==MANDEL || fractype==MANDELFP)
{
clear_zoombox();
Jiim(JIIM);
}
#endif
else
buzzer(2);
break;
case '\\': /* return to prev image */
if (--historyptr < 0)
historyptr = MAXHISTORY-1;
xxmax = history[historyptr].xxmax;
xxmin = history[historyptr].xxmin;
yymax = history[historyptr].yymax;
yymin = history[historyptr].yymin;
xx3rd = history[historyptr].xx3rd;
yy3rd = history[historyptr].yy3rd;
{
int j;
for(j=0;j<MAXPARAMS;j++)
param[j] = history[historyptr].param[j];
}
fractype = history[historyptr].fractype;
curfractalspecific = &fractalspecific[fractype];
zoomoff = 1;
initmode = adapter;
if (curfractalspecific->isinteger != 0 &&
curfractalspecific->tofloat != NOFRACTAL)
usr_floatflag = 0;
if (curfractalspecific->isinteger == 0 &&
curfractalspecific->tofloat != NOFRACTAL)
usr_floatflag = 1;
historyflag = 1; /* avoid re-store parms due to rounding errs */
goto imagestart;
case 'd': /* shell to MS-DOS */
stackscreen();
#ifndef XFRACT
if (axmode == 0 || axmode > 7) {
static char far dosmsg[]={"\
Note: Your graphics image is still squirreled away in your video\n\
adapter's memory. Switching video modes will clobber part of that\n\
image. Sorry - it's the best we could do."};
putstring(0,0,7,dosmsg);
movecursor(6,0);
}
#endif
shell_to_dos();
unstackscreen();
/* calc_status = 0; */
break;
case 'c': /* switch to color cycling */
case '+': /* rotate palette */
case '-': /* rotate palette */
clear_zoombox();
memcpy(olddacbox,dacbox,256*3);
rotate((kbdchar == 'c') ? 0 : ((kbdchar == '+') ? 1 : -1));
if (memcmp(olddacbox,dacbox,256*3))
colorstate = 1;
continue;
case 'e': /* switch to color editing */
clear_zoombox();
if (dacbox[0][0] != 255 && !reallyega && colors >= 16
&& dotmode != 11) {
int oldhelpmode;
oldhelpmode = helpmode;
memcpy(olddacbox,dacbox,256*3);
helpmode = HELPXHAIR;
EditPalette();
helpmode = oldhelpmode;
if (memcmp(olddacbox,dacbox,256*3))
colorstate = 1;
}
continue;
case 's': /* save-to-disk */
diskisactive = 1; /* flag for disk-video routines */
note_zoom();
savetodisk(savename);
restore_zoom();
diskisactive = 0; /* flag for disk-video routines */
continue;
case '#': /* 3D overlay */
#ifdef XFRACT
case F3: /* 3D overlay */
#endif
clear_zoombox();
overlay3d = 1;
case '3': /* restore-from (3d) */
do_3d_transform:
if(overlay3d)
display3d = 2; /* for <b> command */
else
display3d = 1;
case 'r': /* restore-from */
comparegif = 0;
frommandel = 0;
if(kbdchar == 'r') {
if(debugflag == 50) {
comparegif = overlay3d = 1;
if (initbatch == 2) {
stackscreen(); /* save graphics image */
strcpy(readname,savename);
showfile = 0;
goto restorestart;
}
}
else
comparegif = overlay3d = 0;
display3d = 0;
}
stackscreen(); /* save graphics image */
if (overlay3d)
stacked = 0;
else
stacked = 1;
if (resave_flag) {
updatesavename(savename); /* do the pending increment */
resave_flag = started_resaves = 0;
}
showfile = -1;
goto restorestart;
case 'b': /* make batch file */
make_batch_file();
break;
case 'p': /* print current image */
note_zoom();
Print_Screen();
restore_zoom();
if (!keypressed())
buzzer(0);
else {
buzzer(1);
getakey();
}
continue;
case ENTER: /* Enter */
case ENTER_2: /* Numeric-Keypad Enter */
#ifdef XFRACT
XZoomWaiting = 0;
#endif
if (zwidth != 0.0) { /* do a zoom */
init_pan_or_recalc(0);
kbdmore = 0;
}
if (calc_status != 4) /* don't restart if image complete */
kbdmore = 0;
break;
case CTL_ENTER: /* control-Enter */
case CTL_ENTER_2: /* Control-Keypad Enter */
init_pan_or_recalc(1);
kbdmore = 0;
zoomout(); /* calc corners for zooming out */
break;
case INSERT: /* insert */
setvideotext(); /* force text mode */
goto restart;
case LEFT_ARROW: /* cursor left */
case RIGHT_ARROW: /* cursor right */
case UP_ARROW: /* cursor up */
case DOWN_ARROW: /* cursor down */
case LEFT_ARROW_2: /* Ctrl-cursor left */
case RIGHT_ARROW_2: /* Ctrl-cursor right */
case UP_ARROW_2: /* Ctrl-cursor up */
case DOWN_ARROW_2: /* Ctrl-cursor down */
move_zoombox(kbdchar);
break;
case CTL_HOME: /* Ctrl-home */
if (boxcount && (curfractalspecific->flags&NOROTATE) == 0) {
i = key_count(CTL_HOME);
if ((zskew -= 0.02*i) < -0.48)
zskew = -0.48;
}
break;
case CTL_END: /* Ctrl-end */
if (boxcount && (curfractalspecific->flags&NOROTATE) == 0) {
i = key_count(CTL_END);
if ((zskew += 0.02*i) > 0.48)
zskew = 0.48;
}
break;
case CTL_PAGE_UP: /* Ctrl-pgup */
if (boxcount)
chgboxi(0,-2*key_count(CTL_PAGE_UP));
break;
case CTL_PAGE_DOWN: /* Ctrl-pgdn */
if (boxcount)
chgboxi(0,2*key_count(CTL_PAGE_DOWN));
break;
case PAGE_UP: /* page up */
if (zoomoff == 1)
if (zwidth == 0) { /* start zoombox */
zwidth = zdepth = 1;
zrotate = zskew = 0;
zbx = zby = 0;
find_special_colors();
boxcolor = color_bright;
}
else
resizebox(0-key_count(PAGE_UP));
break;
case PAGE_DOWN: /* page down */
if (boxcount) {
if (zwidth >= .999 && zdepth >= 0.999) /* end zoombox */
zwidth = 0;
else
resizebox(key_count(PAGE_DOWN));
}
break;
case CTL_MINUS: /* Ctrl-kpad- */
if (boxcount && (curfractalspecific->flags&NOROTATE) == 0)
zrotate += key_count(CTL_MINUS);
break;
case CTL_PLUS: /* Ctrl-kpad+ */
if (boxcount && (curfractalspecific->flags&NOROTATE) == 0)
zrotate -= key_count(CTL_PLUS);
break;
case CTL_INSERT: /* Ctrl-ins */
boxcolor += key_count(CTL_INSERT);
break;
case CTL_DEL: /* Ctrl-del */
boxcolor -= key_count(CTL_DEL);
break;
case DELETE: /* select video mode from list */
stackscreen();
kbdchar = select_video_mode(adapter);
if (check_vidmode_key(0,kbdchar) >= 0) /* picked a new mode? */
discardscreen();
else
unstackscreen();
/* fall through */
default: /* other (maybe a valid Fn key) */
if ((k = check_vidmode_key(0,kbdchar)) >= 0) {
adapter = k;
/* if (videotable[adapter].dotmode != 11 Took out so that */
/* || videotable[adapter].colors != colors) DAC is not reset */
/* savedac = 0; when changing video modes */
calc_status = 0;
kbdmore = 0;
continue;
}
break;
} /* end of the big switch */
if (zoomoff == 1 && kbdmore == 1) /* draw/clear a zoom box? */
drawbox(1);
#ifdef XFRACT
if (resizeWindow()) {
calc_status = -1;
}
#endif
}
}
}
/* read keystrokes while = specified key, return 1+count; */
/* used to catch up when moving zoombox is slower than keyboard */
int key_count(int keynum)
{ int ctr;
ctr = 1;
while (keypressed() == keynum) {
getakey();
++ctr;
}
return ctr;
}
/* do all pending movement at once for smooth mouse diagonal moves */
static void move_zoombox(int keynum)
{ int vertical, horizontal, getmore;
if (boxcount == 0)
return;
vertical = horizontal = 0;
getmore = 1;
while (getmore) {
switch (keynum) {
case LEFT_ARROW: /* cursor left */
--horizontal;
break;
case RIGHT_ARROW: /* cursor right */
++horizontal;
break;
case UP_ARROW: /* cursor up */
--vertical;
break;
case DOWN_ARROW: /* cursor down */
++vertical;
break;
case LEFT_ARROW_2: /* Ctrl-cursor left */
horizontal -= 5;
break;
case RIGHT_ARROW_2: /* Ctrl-cursor right */
horizontal += 5;
break;
case UP_ARROW_2: /* Ctrl-cursor up */
vertical -= 5;
break;
case DOWN_ARROW_2: /* Ctrl-cursor down */
vertical += 5;
break;
default:
getmore = 0;
}
if (getmore) {
if (getmore == 2) /* eat last key used */
getakey();
getmore = 2;
keynum = keypressed(); /* next pending key */
}
}
if (horizontal!=0)
moveboxf((double)horizontal/dxsize,0.0);
if (vertical!=0)
moveboxf(0.0,(double)vertical/dysize);
}
/* displays differences between current image file and new image */
static FILE *cmp_fp;
static errcount;
int cmp_line(BYTE *pixels, int linelen)
{
extern int rowcount;
int row,col;
int oldcolor;
if((row = rowcount++) == 0) {
errcount = 0;
cmp_fp = fopen("cmperr",(initbatch)?"a":"w");
outln_cleanup = cmp_line_cleanup;
}
if(pot16bit) { /* 16 bit info, ignore odd numbered rows */
if((row & 1) != 0) return(0);
row >>= 1;
}
for(col=0;col<linelen;col++) {
oldcolor=getcolor(col,row);
if(oldcolor==pixels[col])
putcolor(col,row,0);
else {
if(oldcolor==0)
putcolor(col,row,1);
++errcount;
if(initbatch == 0)
fprintf(cmp_fp,"#%5d col %3d row %3d old %3d new %3d\n",
errcount,col,row,oldcolor,pixels[col]);
}
}
return(0);
}
static void cmp_line_cleanup()
{
char *timestring;
time_t ltime;
if(initbatch) {
time(<ime);
timestring = ctime(<ime);
timestring[24] = 0; /*clobber newline in time string */
fprintf(cmp_fp,"%s compare to %s has %5d errs\n",
timestring,readname,errcount);
}
fclose(cmp_fp);
}
int pot_line(BYTE *pixels, int linelen)
{
extern int rowcount;
int row,col,saverowcount;
if (rowcount == 0)
if (pot_startdisk() < 0)
return -1;
saverowcount = rowcount;
row = (rowcount >>= 1);
if ((saverowcount & 1) != 0) /* odd line */
row += ydots;
else /* even line */
if (dotmode != 11) /* display the line too */
out_line(pixels,linelen);
for (col = 0; col < xdots; ++col)
writedisk(col+sxoffs,row+syoffs,*(pixels+col));
rowcount = saverowcount + 1;
return(0);
}
static int call_line3d(BYTE *pixels, int linelen)
{
/* this routine exists because line3d might be in an overlay */
return(line3d(pixels,linelen));
}
void clear_zoombox()
{
zwidth = 0;
drawbox(0);
reset_zoom_corners();
}
void reset_zoom_corners()
{
xxmin = sxmin;
xxmax = sxmax;
xx3rd = sx3rd;
yymax = symax;
yymin = symin;
yy3rd = sy3rd;
}
static char far *savezoom;
extern int boxcount;
extern char boxx[],boxy[];
extern char boxvalues[];
static void note_zoom()
{
if (boxcount) { /* save zoombox stuff in far mem before encode (mem reused) */
if ((savezoom = farmemalloc((long)(5*boxcount))) == NULL)
clear_zoombox(); /* not enuf mem so clear the box */
else {
reset_zoom_corners(); /* reset these to overall image, not box */
far_memcpy(savezoom,boxx,boxcount*2);
far_memcpy(savezoom+boxcount*2,boxy,boxcount*2);
far_memcpy(savezoom+boxcount*4,boxvalues,boxcount);
}
}
}
static void restore_zoom()
{
if (boxcount) { /* restore zoombox arrays */
far_memcpy(boxx,savezoom,boxcount*2);
far_memcpy(boxy,savezoom+boxcount*2,boxcount*2);
far_memcpy(boxvalues,savezoom+boxcount*4,boxcount);
farmemfree(savezoom);
drawbox(1); /* get the xxmin etc variables recalc'd by redisplaying */
}
}
/*
Function setup287code is called by main() when a 287
or better fpu is detected.
*/
#define ORBPTR(x) fractalspecific[x].orbitcalc
static void setup287code()
{
ORBPTR(MANDELFP) = ORBPTR(JULIAFP) = FJuliafpFractal;
ORBPTR(BARNSLEYM1FP) = ORBPTR(BARNSLEYJ1FP) = FBarnsley1FPFractal;
ORBPTR(BARNSLEYM2FP) = ORBPTR(BARNSLEYJ2FP) = FBarnsley2FPFractal;
ORBPTR(MANOWARFP) = ORBPTR(MANOWARJFP) = FManOWarfpFractal;
ORBPTR(MANDELLAMBDAFP) = ORBPTR(LAMBDAFP) = FLambdaFPFractal;
}
int sound_line(pixels, linelen)
BYTE *pixels;
int linelen;
{
extern int rowcount;
extern int basehertz;
extern int xdots;
extern int colors;
extern int orbit_delay;
int i;
for(i=0;i<linelen;i++)
{
putcolor(i,rowcount,pixels[i]);
if(orbit_delay > 0)
sleepms(orbit_delay);
snd((int)(pixels[i]*3000/colors+basehertz));
if(keypressed())
{
nosnd();
return(-1);
}
}
nosnd();
rowcount++;
return(0);
}
int check_key()
{
int key;
if((key = keypressed()) != 0) {
if(key != 'o' && key != 'O') {
fflush(stdout);
return(-1);
}
getakey();
if (dotmode != 11)
show_orbit = 1 - show_orbit;
}
return(0);
}
/* timer function:
timer(0,(*fractal)()) fractal engine
timer(1,NULL,int width) decoder
timer(2) encoder
*/
#ifndef XFRACT
int timer(int timertype,int(*subrtn)(),...)
#else
int timer(va_alist)
va_dcl
#endif
{
va_list arg_marker; /* variable arg list */
char *timestring;
time_t ltime;
FILE *fp;
int out;
int i;
int do_bench;
#ifndef XFRACT
va_start(arg_marker,subrtn);
#else
int timertype;
int (*subrtn)();
va_start(arg_marker);
timertype = va_arg(arg_marker, int);
subrtn = ( int (*)()) va_arg(arg_marker, int *);
#endif
do_bench = timerflag; /* record time? */
if (timertype == 2) /* encoder, record time only if debug=200 */
do_bench = (debugflag == 200);
if(do_bench)
fp=fopen("bench","a");
timer_start = clock_ticks();
switch(timertype) {
case 0:
out = (*subrtn)();
break;
case 1:
i = va_arg(arg_marker,int);
out = decoder(i); /* not indirect, safer with overlays */
break;
case 2:
out = encoder(); /* not indirect, safer with overlays */
break;
}
/* next assumes CLK_TCK is 10^n, n>=2 */
timer_interval = (clock_ticks() - timer_start) / (CLK_TCK/100);
if(do_bench) {
time(<ime);
timestring = ctime(<ime);
timestring[24] = 0; /*clobber newline in time string */
switch(timertype) {
case 1:
fprintf(fp,"decode ");
break;
case 2:
fprintf(fp,"encode ");
break;
}
fprintf(fp,"%s type=%s resolution = %dx%d maxiter=%d",
timestring,
curfractalspecific->name,
xdots,
ydots,
maxit);
fprintf(fp," time= %ld.%02ld secs\n",timer_interval/100,timer_interval%100);
if(fp != NULL)
fclose(fp);
}
return(out);
}